package sf.database.jdbc.rowmapper;

import sf.common.exception.SmallOrmException;
import sf.database.OrmConfig;
import sf.database.dao.DBContext;
import sf.database.meta.MetaHolder;

import javax.persistence.SqlResultSetMapping;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @Author: sxf
 * @Date: 2018/3/27
 */
public class RowMapperHelp {

    /**
     * 获取转为rowmapper
     * @param beanClass
     * @param <T>
     * @return
     */
    public static <T> RowMapper<T> getRowMapper(Class<T> beanClass, DBContext context) {
        RowMapper<T> rowMapper;
        if (beanClass.isArray()) {
            if (beanClass == Object[].class) {
                rowMapper = (RowMapper<T>) new ArrayRowMapper();
            } else {
                throw new SmallOrmException("数组类型返回只支持 Object[] ");
            }
        } else if (Map.class.isAssignableFrom(beanClass)) {
            rowMapper = (RowMapper<T>) new MapRowMapper();
        } else if (Set.class.isAssignableFrom(beanClass)) {
            rowMapper = (RowMapper<T>) new SetRowMapper();
        } else if (List.class.isAssignableFrom(beanClass) || Collection.class.isAssignableFrom(beanClass)) {
            rowMapper = (RowMapper<T>) new ListRowMapper();
        } else if (beanClass.isPrimitive() || beanClass.isEnum() || beanClass.getName().startsWith("java.")) {
            rowMapper = new SingleColumnRowMapper<T>(beanClass);
        } else {
            rowMapper = getBeanRowMapper(beanClass, context);
        }
        return rowMapper;
    }

    /**
     * 获取转为 BeanRowMapper
     * @param beanClass
     * @param <T>
     * @return
     */
    public static <T> BeanRowMapper<T> getBeanRowMapper(Class<T> beanClass, DBContext context) {
        boolean useTail = OrmConfig.getInstance().isUseTail() || (MetaHolder.getMeta(beanClass).getTailField() != null)
                || (context != null && context.isUseTail());
        boolean keepUpdate = context != null && context.isKeepUpdate();
        return new BeanRowMapper<T>(beanClass, useTail, keepUpdate);
    }

    public static  JPABeanRowMapper getBeanRowMapper(SqlResultSetMapping resultSetMapping, DBContext context) {
        boolean useTail = OrmConfig.getInstance().isUseTail() || (context != null && context.isUseTail());
        boolean keepUpdate = context != null && context.isKeepUpdate();
        return new JPABeanRowMapper(resultSetMapping, useTail, keepUpdate);
    }
}
